package com.yhm.mybatis.intercepts;


import com.yhm.mybatis.dto.PageInfo;
import org.apache.ibatis.executor.parameter.ParameterHandler;
import org.apache.ibatis.executor.statement.StatementHandler;
import org.apache.ibatis.mapping.BoundSql;
import org.apache.ibatis.mapping.MappedStatement;
import org.apache.ibatis.plugin.*;
import org.apache.ibatis.reflection.MetaObject;
import org.apache.ibatis.reflection.SystemMetaObject;

import java.sql.Connection;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.util.Map;
import java.util.Properties;

@Intercepts(@Signature(type = StatementHandler.class,
        method = "prepare",
        args = {Connection.class, Integer.class}))
public class yhmIntercepts implements Interceptor {
  @Override
  public Object intercept(Invocation invocation) throws Throwable {
    System.out.println("进入到了插件");

    StatementHandler statementHandler = (StatementHandler) invocation.getTarget();

    BoundSql boundSql = statementHandler.getBoundSql();

    System.out.println("原来的sql语句"+boundSql.getSql());

// 分页参数
    Object paramObj = boundSql.getParameterObject();

    // statementHandler 转成 metaObject
    MetaObject metaObject = SystemMetaObject.forObject(statementHandler);

    // spring context.getBean("userBean")
    MappedStatement mappedStatement = (MappedStatement) metaObject.getValue("delegate.mappedStatement");
    // 获取mapper接口中的方法名称  selectUserByPage
    String mapperMethodName = mappedStatement.getId();
    if (true)
//      (mapperMethodName.matches(".*ByPage$"))
    {
      Map<String, Object> params = (Map<String, Object>) paramObj;

      PageInfo pageInfo = (PageInfo) params.get("page"); // map.put("page", PageInfo);
      //  select * from user;
      String countSql = "select count(0) from (" + boundSql.getSql() + ") a";
      System.out.println("查询总数的sql : " + countSql);

      // 执行jdbc操作
      Connection connection = (Connection) invocation.getArgs()[0];
      PreparedStatement countStatement = connection.prepareStatement(countSql);
      ParameterHandler parameterHandler = (ParameterHandler) metaObject.getValue("delegate.parameterHandler");
      parameterHandler.setParameters(countStatement);
      ResultSet rs = countStatement.executeQuery();
      if (rs.next()) {
        pageInfo.setTotalNumber(rs.getInt(1));
      }
      rs.close();
      countStatement.close();

      // 改造sql limit
      String pageSql = this.generaterPageSql(boundSql.getSql(), pageInfo);
      System.out.println("分页sql：" + pageSql);

      metaObject.setValue("delegate.boundSql.sql", pageSql);

    }

    return invocation.proceed();
  }
  // 根据原始sql 生成 带limit sql
  public String generaterPageSql(String sql, PageInfo pageInfo) {
    StringBuffer sb = new StringBuffer();
    sb.append(sql);
    sb.append(" limit " + pageInfo.getStartIndex() + " , " + pageInfo.getTotalSelect());
    return sb.toString();
  }

  @Override
  public Object plugin(Object target) {
    return Plugin.wrap(target, this);
  }

  @Override
  public void setProperties(Properties properties) {

  }
}
